using System.ComponentModel;

using VSTalk.Engine.Core.Context;
using VSTalk.Engine.Core.EntitySession;
using VSTalk.Engine.Core.EnvironmentManagers.UI;
using VSTalk.Engine.Core.XmppCommunication;
using VSTalk.Engine.Core.XmppCommunication.Services.RoomManager;
using VSTalk.Engine.Utils;
using VSTalk.Engine.ViewModel.History;
using VSTalk.Engine.Windows;
using VSTalk.Model;

namespace VSTalk.Engine.ViewModel.ContactList.ClientResources
{
    public class RoomResourceViewModel : IClientResource
    {
        private readonly Room _room;
        private IResourceUpdateHandler _handler;

        public Room Room
        {
            get { return _room; }
        }

        private static IWindowManager WindowManager
        {
            get { return AppServices.Get<IWindowManager>(); }
        }

        private static ISessionModel SessionModel
        {
            get { return AppServices.Get<ISessionModel>(); }
        }

        public IRoomContext Context
        {
            get { return SessionModel.GetRoomContext(Room); }
        }

        private IRoomManager _roomManager;

        private PropertyChangedEventHandler _roomEvent;

        public IRoomManager RoomManager
        {
            get { return _roomManager ?? (_roomManager = CommunicationServiceFactory.Create<RoomManager>(Room)); }
        }

        private IModelContext ModelContext
        {
            get { return AppServices.Get<IModelContext>(); }
        }

        public RelayCommand OpenRoom { get; private set; }
        public RelayCommand JoinRoom { get; private set; }
        public RelayCommand LeaveRoom { get; private set; }
        public RelayCommand DeleteRoom { get; private set; }
        public RelayCommand ShowLog { get; private set; }

        public RoomResourceViewModel(Room room)
        {
            _room = room;
            SetCommands();
        }

        public void StartListen()
        {
            _roomEvent = (sender, args) =>
            {
                if (_handler != null)
                {
                    _handler.Update();
                }
            };
            _room.PropertyChanged += _roomEvent;
        }

        public void StopListen()
        {
            _room.PropertyChanged -= _roomEvent;
        }

        private void SetCommands()
        {
            OpenRoom = new RelayCommand(OpenRoomExecuted);
            JoinRoom = new RelayCommand(JoinRoomExecuted);
            LeaveRoom = new RelayCommand(LeaveRoomExecuted);
            DeleteRoom = new RelayCommand(DeleteRoomExecuted);
            ShowLog = new RelayCommand(ShowLogExecuted);
        }

        private void ShowLogExecuted()
        {
            var client = ModelContext.GetClientByRoom(Room);
            var vm = new HistoryExplorerViewModel(client, Context.Bare);
            var wnd = new HistoryExplorerWindow();
            wnd.DataContext = vm;
            vm.StartListen();
            wnd.Closed += (sender, args) => vm.StopListen();
            wnd.Show();
        }

        private void DeleteRoomExecuted()
        {
            RoomManager.DeleteRoom(Room.Id);
        }

        private void LeaveRoomExecuted()
        {
            RoomManager.LeaveRoom(Room.Id);
        }

        private void JoinRoomExecuted()
        {
            RoomManager.JoinRoom(Room.Id);
        }

        private void OpenRoomExecuted()
        {
            if (!Context.IsActive)
            {
                RoomManager.JoinRoom(Room.Id);
            }
            WindowManager.ShowChatWindow(Room);
        }

        public object Model
        {
            get { return _room; }
        }

        public void Subscribe(IResourceUpdateHandler handler)
        {
            _handler = handler;
        }
    }
}